import { HTMLAttributes, useEffect, useRef, useState } from "react"
import { useRafState } from "ahooks"
import { useSize } from "ahooks"
import { motion } from "motion/react"
import styled from "@emotion/styled"

type Props = HTMLAttributes<HTMLDivElement> & {}

export default function ScaleBox(props: Props) {
    const { children, className: _className = "", style: _style = {}, ..._props } = props

    const [ready, setReady] = useRafState(false)
    const rootRef = useRef<HTMLDivElement>(null)
    const childRef = useRef<HTMLDivElement>(null)
    const rootSize = useSize(rootRef)
    const childSize = useSize(childRef)

    const [scale, setScale] = useState(1)

    useEffect(() => {
        if (
            rootRef.current &&
            rootSize?.width &&
            rootSize?.height &&
            childSize?.width &&
            childSize?.height
        ) {
            const sizeRatio = childSize.width / childSize.height
            rootRef.current.style.height = `${rootSize.width / sizeRatio}px`
            const scaleRatio = rootSize.width / childSize.width
            setScale(scaleRatio)
            setReady(true)
        }
    }, [rootSize, childSize, setScale, setReady])

    return (
        <div
            ref={rootRef}
            className={`${_className}`}
            style={{
                ..._style,
                visibility: ready ? "visible" : "hidden",
            }}
            {..._props}
        >
            <ScaleBoxChild
                ref={childRef}
                style={{
                    transform: `scale(${scale})`,
                    pointerEvents: "none",
                }}
            >
                {children}
            </ScaleBoxChild>
        </div>
    )
}

const ScaleBoxChild = styled(motion.div)`
    will-change: transform;
    display: inline-flex;
    transform-origin: top left;
`
